package com.folderit.apps.rooms;

import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;

import com.folderit.apps.rooms.data.RoomsContract;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * Created by César on 13/12/2014.
 */
public class Utility {
    public static boolean notificationsEnabled(Context context) {
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);

        // Default true
        return prefs.getBoolean(context.getString(R.string.pref_enable_notifications_key), true);
    }

    static String formatDate(String dateString) {
        Date date = RoomsContract.getDateFromDb(dateString);
        return DateFormat.getDateInstance().format(date);
    }

    // Format used for storing dates in the database.  ALso used for converting those strings
    // back into date objects for comparison/processing.
    public static final String DATE_FORMAT = "yyyyMMdd";
    public static final String DATETIME_FORMAT = "yyyyMMddHHmmss";

    /**
     * Helper method to convert the database representation of the date into something to display
     * to users.  As classy and polished a user experience as "20140102121300" is, we can do better.
     *
     * @param context Context to use for resource localization
     * @param datetimeStr The db formatted datetime string.
     * @return a user-friendly representation of the date.
     */
    public static String getFriendlyDayString(Context context, String datetimeStr) {
        // The day string for forecast uses the following logic:
        // For today: "Today, June 8"
        // For tomorrow:  "Tomorrow"
        // For the next 5 days: "Wednesday" (just the day name)
        // For all days after that: "Mon Jun 8"

        Date todayDate = new Date();
        String todayStr = RoomsContract.getDbDateTimeString(todayDate);
        Date inputDate = RoomsContract.getDateTimeFromDb(datetimeStr);

        // If the date we're building the String for is today's date, the format
        // is "Today, June 24"
        if (todayStr.equals(datetimeStr)) {
            String today = context.getString(R.string.today);
            int formatId = R.string.format_full_friendly_date;
            return String.format(context.getString(
                    formatId,
                    today,
                    getFormattedMonthDay(context, datetimeStr)));
        } else {
            Calendar cal = Calendar.getInstance();
            cal.setTime(todayDate);
            cal.add(Calendar.DATE, 7);
            String weekFutureString = RoomsContract.getDbDateTimeString(cal.getTime());

            if (datetimeStr.compareTo(weekFutureString) < 0) {
                // If the input date is less than a week in the future, just return the day name.
                return getDayName(context, datetimeStr);
            } else {
                // Otherwise, use the form "Mon Jun 3"
                SimpleDateFormat shortenedDateFormat = new SimpleDateFormat("EEE MMM dd");
                return shortenedDateFormat.format(inputDate);
            }
        }
    }

    /**
     * Given a day, returns just the name to use for that day.
     * E.g "today", "tomorrow", "wednesday".
     *
     * @param context Context to use for resource localization
     * @param datetimeStr The db formatted datetime string.
     * @return
     */
    public static String getDayName(Context context, String datetimeStr) {
        SimpleDateFormat dbDateFormat = new SimpleDateFormat(Utility.DATETIME_FORMAT);
        try {
            Date inputDate = dbDateFormat.parse(datetimeStr);
            Date todayDate = new Date();
            // If the date is today, return the localized version of "Today" instead of the actual
            // day name.
            if (RoomsContract.getDbDateString(todayDate).equals(datetimeStr)) {
                return context.getString(R.string.today);
            } else {
                // If the date is set for tomorrow, the format is "Tomorrow".
                Calendar cal = Calendar.getInstance();
                cal.setTime(todayDate);
                cal.add(Calendar.DATE, 1);
                Date tomorrowDate = cal.getTime();
                if (RoomsContract.getDbDateString(tomorrowDate).equals(
                        datetimeStr)) {
                    return context.getString(R.string.tomorrow);
                } else {
                    // Otherwise, the format is just the day of the week (e.g "Wednesday".
                    SimpleDateFormat dayFormat = new SimpleDateFormat("EEEE");
                    return dayFormat.format(inputDate);
                }
            }
        } catch (ParseException e) {
            e.printStackTrace();
            // It couldn't process the date correctly.
            return "";
        }
    }

    /**
     * Converts db date format to the format "Month day", e.g "June 24".
     *
     * @param context Context to use for resource localization
     * @param datetimeStr The db formatted date string, expected to be of the form specified
     *                in Utility.DATE_FORMAT
     * @return The day in the form of a string formatted "December 6"
     */
    public static String getFormattedMonthDay(Context context, String datetimeStr) {
        SimpleDateFormat dbDateFormat = new SimpleDateFormat(Utility.DATETIME_FORMAT);
        try {
            Date inputDate = dbDateFormat.parse(datetimeStr);
            SimpleDateFormat monthDayFormat = new SimpleDateFormat("MMMM dd");
            String monthDayString = monthDayFormat.format(inputDate);
            return monthDayString;
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * Receives a datetime text formatted as 'yyyyMMddHHmmss'
     * and returns the time formatted as HH:mm.
     * @param dateTimeText DateTime Text.
     * @return Formatted time.
     */
    public static String formatTime(String dateTimeText) {
        final String TIME_FORMAT = "HH:mm";

        Date date = RoomsContract.getDateTimeFromDb(dateTimeText);
        SimpleDateFormat sdf = new SimpleDateFormat(TIME_FORMAT);

        return sdf.format(date);
    }

    public static String getDurationFormat(Context context, String from, String to) {

        Date fromDate = RoomsContract.getDateTimeFromDb(from);
        Date toDate = RoomsContract.getDateTimeFromDb(to);

        long diff = toDate.getTime() - fromDate.getTime();
        // long diffSeconds = diff / 1000 % 60;
        long diffMinutes = diff / (60 * 1000) % 60;
        long diffHours = diff / (60 * 60 * 1000);

        if (diffHours > 0) {
            return String.format(
                    context.getString(R.string.format_reservation_duration_hours),
                    diffHours,
                    diffMinutes);
        }

        return String.format(context.getString(R.string.format_reservation_duration_minutes),
                diffMinutes);
    }

    public static String formatBeginEndDuration(Context context, String begin, String end)
    {
        String beginTimeFormatted = Utility.formatTime(begin);
        String endTimeFormatted = Utility.formatTime(end);

        // Get duration
        String duration = Utility.getDurationFormat(context, begin, end);

        return String.format(
                        context.getString(R.string.format_list_item_reservation_from_to),
                        beginTimeFormatted,
                        endTimeFormatted,
                        duration);
    }

    public static int getRoomIconIdByColorId(int colorId)
    {
        switch (colorId) {
            case RoomsContract.RoomColor.RED:
                return R.drawable.folderit_red;

            case RoomsContract.RoomColor.BLUE:
                return R.drawable.folderit_blue;

            case RoomsContract.RoomColor.GREEN:
                return R.drawable.folderit_green;

            case RoomsContract.RoomColor.YELLOW:
                return R.drawable.folderit_yellow;

            case RoomsContract.RoomColor.ORANGE:
                return R.drawable.folderit_orange;

            case RoomsContract.RoomColor.VIOLET:
                return R.drawable.folderit_violet;

            default:
                return R.drawable.ic_launcher;
        }
    }
}
